/**
 * 获取access_token
 * 全局唯一、有效期为2小时、接口每天最多两千次
 * GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
 */
const { appID, appsecret } = require('../config')
const reqpromise = require('request-promise-native')
const { writeFileSync, readFile } = require('fs')
const menu = require('./menu')

class SubScription {
    constructor() {}
    async getAccessToken() {
        const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appID}&secret=${appsecret}`
        const result = await reqpromise({ method: 'GET', url, json: true })
        if(!result.access_token) {
            throw Error('access_token未拿到')
        }
        result.expires_in = Date.now() + (result.expires_in - 300) * 1000
        return result
    }
    saveAccessToken(accessToken) {
        writeFileSync('./accessToken.txt', JSON.stringify(accessToken), err => {
            if(!err) {
                console.log('文件保存成功')
            }else {
                console.log(err)
            }
        })
    }
    readAccessToken() {
        return new Promise((resolve, reject) => {
            readFile('./accessToken.txt', (err, data) => {
                if(!err) {
                    console.log('文件读取成功')
                    resolve(JSON.parse(data))
                }else {
                    reject(err)
                }
            })
        })
    }
    isValidAccessToken(data) {
        if(!data && !data.accessToken && !data.expires_in) {
            return false;
        }
        // accessToken过期
        return data.expires_in < Date.now()
    }
    fetchAccessToken() {
        if(this.access_token && this.expires_in && this.isValidAccessToken(this)) {
            return Promise.resolve({
                access_token: this.access_token,
                expires_in: this.expires_in
            })
        }
        return this.readAccessToken()
            .then(async res => {
                if(this.isValidAccessToken(res)) {
                    // 本地文件有效
                    return Promise.resolve(res)
                }else {
                    // 本地文件过期
                    const res1 = await this.getAccessToken()
                    await this.saveAccessToken(res1)
                    return Promise.resolve(res1)
                }
            })
            .catch(async err => {
                // 本地没有文件
                const res = await this.getAccessToken()
                await this.saveAccessToken(res)
                return Promise.resolve(res)
            })
            .then(res => {
                this.access_token = res.access_token
                this.expires_in = res.expires_in
                return Promise.resolve(res)
            })
    }
    createMenu(menu) {
        return new Promise(async (resolve, reject) => {
            const data = await this.fetchAccessToken()
            const url = `https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${data.access_token}`
            const result = await reqpromise({method: 'POST', url, json: true, body: menu})
            resolve(result)
        })
    }
    deleteMenu() {
        return new Promise(async (resolve, reject) => {
            const data = await this.fetchAccessToken()
            const url = `https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=${data.access_token}`
            const result = await reqpromise({method: 'GET', url, json: true})
            resolve(result)
        })
    }
}


(async () => {
    const sub = new SubScription()
    const result1 = await sub.deleteMenu()
    const result2 = await sub.createMenu(menu)
    console.log(result2)
})()
